package cn.com.cpic.insurance.rulecheck.core;

import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

/**
 * <pre>
 * 这是一个精简的可修改集合实现，在这个集合中实际存储的是元素的token，而不是元素本身。
 * 这样做的目的是减少集合持久化的大小，同时为了避免添加未知的元素。
 * 添加的所有的元素都必须在另一个参照集合内，所谓未知元素，就是指不在参照集合内的元素。
 * 插入未知元素会返回false。
 * </pre>
 * 
 * @author 代波
 * @since 2011-8-23
 * @param <K> 参照Map中key的类型
 * @param <V> 参照Map中value的类型，同时也是集合中元素的类型
 */
public class ReferModifiableSet<K, V extends Tokenable<K>> implements ModifiableSet<V> {
	private static final long serialVersionUID = -3737257636062355094L;

	protected final ModifiableMap<K, V> referMap;// 参照集合
	protected final Set<K> tokenSet;// 自身元素的token集合

	public ReferModifiableSet(ModifiableMap<K, V> referMap, Set<V> set) {
		this.referMap = referMap;
		this.tokenSet = Collections.synchronizedSet(new HashSet<K>());
		if (set != null) {
			for (V t : set) {
				add(t);
			}
		}
	}

	public ReferModifiableSet(ModifiableMap<K, V> referMap, V... sets) {
		this.referMap = referMap;
		this.tokenSet = Collections.synchronizedSet(new HashSet<K>());
		if (sets != null) {
			for (V t : sets) {
				add(t);
			}
		}
	}

	public boolean contains(V c) {
		return tokenSet.contains(c.getToken());
	}

	public boolean add(V c) {
		if (referMap.containsKey(c.getToken())) {
			return tokenSet.add(c.getToken());
		} else
			return false;
	}

	public boolean remove(V c) {
		return tokenSet.remove(c.getToken());
	}

	public Iterator<V> iterator() {
		return new Iterator<V>() {
			private Iterator<K> ite = new HashSet<K>(tokenSet).iterator();

			public boolean hasNext() {
				return ite.hasNext();
			}

			public V next() {
				return referMap.get(ite.next());
			}

			public void remove() {
				throw new UnsupportedOperationException();
			}
		};
	}

	public int size() {
		return tokenSet.size();
	}

	public boolean isEmpty() {
		return tokenSet.isEmpty();
	}
}
